#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "xml_tree_parser.h"

static inline void set_new_level(struct xml_parser_tree_node* p, int new_level)
{
    struct list_head* it;
    struct xml_parser_tree_node* cur;

    p->level = new_level;

    list_for_each(it, &p->children)
    {
        cur = (struct xml_parser_tree_node*)it;
        set_new_level(cur, new_level + 1);
    }
}

inline struct xml_parser_tree_node* push_xp_node(struct xml_parser_tree_node* parent, const char* name, int type, int level)
{
    struct xml_parser_tree_node* node = (struct xml_parser_tree_node*)calloc(1, sizeof(struct xml_parser_tree_node));

    if (0 == node)
    {
        fprintf(stderr, "%s - mem calloc failed!\n", __func__);
        return 0;
    }

    INIT_LIST_HEAD(&node->list);
    strcpy(node->name, name);
    node->type = type;
    node->level = level;
    INIT_LIST_HEAD(&node->children);
    INIT_LIST_HEAD(&node->attribs);

    if (parent)
    {
        list_add_tail(&node->list, &parent->children);
        set_new_level(node, parent->level + 1);
    }

    return node;
}

inline void joint_xp_node(struct xml_parser_tree_node* parent, struct xml_parser_tree_node* child)
{
    list_add(&child->list, &parent->children);
    set_new_level(child, parent->level + 1);
}

inline void pop_xp_node(struct xml_parser_tree_node* p)
{
    struct list_head* it;
    struct xml_parser_tree_node* cur;
    struct xml_parser_tree_leaf* cur_attrib;

     while(!list_empty(&p->children))
    {
        cur = (struct xml_parser_tree_node*)p->children.next;
        pop_xp_node(cur);
    }

    while(!list_empty(&p->attribs))
    {
        cur_attrib = (struct xml_parser_tree_leaf*)p->attribs.next;
        pop_xp_attrib(cur_attrib);
    }
    
    list_del(&p->list);
    free(p);
}


inline struct xml_parser_tree_leaf* push_xp_attrib(
    struct xml_parser_tree_node* p,
    const char* name,
    value_check_fp check_fp,
    value_init_fp init_fp
)
{
    struct xml_parser_tree_leaf* node = (struct xml_parser_tree_leaf*)calloc(1, sizeof(struct xml_parser_tree_leaf));

    if (!node)
    {
        fprintf(stderr, "%s - mem calloc failed!\n", __func__);
        return 0;
    }

    INIT_LIST_HEAD(&node->list);
    strcpy(node->name, name);
    node->check_fp = check_fp;
    node->init_fp = init_fp;

    if (p)
    {
        list_add_tail(&node->list, &p->attribs);
    }

    return node;
}

inline void pop_xp_attrib(struct xml_parser_tree_leaf* p)
{
    list_del(&p->list);
    // printf("%s, %s\r\n", __func__, p->name);
    free(p);
}

